package main

import "fmt"

// 不论地址还是结构本身，一律使用.来访问成员,无构造函数
type treeNode struct {
	value       int
	left, right *treeNode
}

// 工厂函数
func createNode(value int) *treeNode {
	return &treeNode{value: value}
}

func (node treeNode) print() {
	fmt.Print(node.value)
}

// 显示定义和命名方法接收者，只有使用指针才可以改变结构内容，nil指针也可以调用方法!
func (node *treeNode) setValue(value int) {
	node.value = value
}

// 遍历
func (node *treeNode) traverse() {
	if node == nil {
		return
	}
	node.left.traverse()
	node.print()
	node.right.traverse()
}

// 值接收者 vs 指针接收者
// 1. 要改变内容必须使用指针接收者
// 2. 结构过大也考虑使用指针接收者
// 3. 一致性:如有指针接收者，最好都是指针接收者
func main() {
	var root treeNode
	root = treeNode{value: 3}
	root.left = &treeNode{}
	root.right = &treeNode{5, nil, nil}
	root.right.left = new(treeNode)
	root.right.left = createNode(2)

	root.right.left.setValue(2)
	root.right.left.print()

	root.traverse()

}
